﻿using System.Linq;
using NUnit.Framework;
using ServiceStack.Stripe;
using ServiceStack.Stripe.Types;
using ServiceStack.Text;

namespace Stripe.Tests;

[TestFixture]
public class StripeGatewayAccountTests : TestsBase
{
    public void DeleteAllCustomersWithEmail(string email)
    {
        StripeCollection<StripeCustomer> existingCustomers = null;
        do
        {
            existingCustomers = gateway.Send(new GetStripeCustomers
            {
                Email = email,
                Limit = 100
            });

            foreach (var customer in existingCustomers.Data)
            {
                DeleteCustomer(customer);
            }
        } while (existingCustomers.Data.Count >= 100);
    }

    private void DeleteCustomer(StripeCustomer account)
    {
        var stripeId = account.Id;
        try
        {
            $"Deleting Customer: {stripeId} - {account.Email} ".Print();
            gateway.Send(new DeleteStripeCustomer
            {
                Id = stripeId
            });
        }
        catch (System.Exception ex)
        {
            $"Error trying to delete {stripeId}: {ex.Message}".Print();
        }
    }

    [Test]
    public void Can_Create_Account()
    {
        DeleteAllCustomersWithEmail("test@email.com");

        var response = gateway.Post(new CreateStripeAccount
        {
            Country = "US",
            Email = "test@email.com",
            LegalEntity = new StripeLegalEntity
            {
                Address = new StripeAddress
                {
                    Line1 = "1 Highway Rd",
                    City = "Brooklyn",
                    State = "NY",
                    Country = "US",
                    PostalCode = "90210",
                },
                Dob = new StripeDate(1980, 1, 1),
                BusinessName = "Business Name",
                FirstName = "First",
                LastName = "Last",
            },
            RequestedCapabilities = new[] {
                StripeCapability.card_payments,
                StripeCapability.transfers,
            }, 
        });

        response.PrintDump();

        Assert.That(response.Keys["secret"], Is.Not.Null);
        Assert.That(response.Keys["publishable"], Is.Not.Null);
        Assert.That(response.BusinessName, Is.EqualTo("Business Name"));
        Assert.That(response.Country, Is.EqualTo("US"));
        Assert.That(response.DefaultCurrency.ToUpper(), Is.EqualTo(Currencies.UnitedStatesDollar));
        Assert.That(response.Email, Is.EqualTo("test@email.com"));

        Assert.That(response.LegalEntity.BusinessName, Is.EqualTo("Business Name"));
        Assert.That(response.LegalEntity.FirstName, Is.EqualTo("First"));
        Assert.That(response.LegalEntity.LastName, Is.EqualTo("Last"));

        var address = response.LegalEntity.Address;
        Assert.That(address.Line1, Is.EqualTo("1 Highway Rd"));
        Assert.That(address.City, Is.EqualTo("Brooklyn"));
        Assert.That(address.State, Is.EqualTo("NY"));
        Assert.That(address.Country, Is.EqualTo("US"));
        Assert.That(address.PostalCode, Is.EqualTo("90210"));

        var dob = response.LegalEntity.Dob;
        Assert.That(dob.Year, Is.EqualTo(1980));
        Assert.That(dob.Month, Is.EqualTo(1));
        Assert.That(dob.Day, Is.EqualTo(1));

        var verification = response.Verification;
        Assert.That(verification.DisabledReason, Is.EqualTo("fields_needed"));
        // Assert.That(verification.DueBy, Is.Null);
        // verification.FieldsNeeded.PrintDump();
        Assert.That(verification.FieldsNeeded, Is.Not.Null);
        Assert.That(verification.FieldsNeeded.Length, Is.EqualTo(8));
    }
}